package com.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.channel.unix.DomainSocketAddress;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
import io.netty.util.ResourceLeakDetector;
import lombok.extern.slf4j.Slf4j;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;


/**
 * @Author Zhangjy
 * @Date 2021/6/24 15:19
 * @Desc
 */
@Slf4j
public class MyClient {

    public static Channel mychannel = null;

    private static Bootstrap bootstrap = null;
    private static EventLoopGroup eventLoopGroup = null;

    public static String url = null;
    public static String ip = null;
    public static Integer port = null;

    public static void connect() throws Exception {
        String uriStr = url;
        URI uri = new URI(uriStr);
        DefaultHttpHeaders headers = new DefaultHttpHeaders();
        WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(
                uri,
                WebSocketVersion.V13,
                null,           // 子协议
                true,           // 允许无安全（如非 wss）
                headers,        // ✅ 传入自定义 headers
                65536);         // 接收帧最大长度

        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(
                                    new HttpClientCodec(),
                                    new HttpObjectAggregator(8192),
                                    new StringDecoder(StandardCharsets.UTF_8),
                                    new MyClientHandler(handshaker));
                        }
                    });

            mychannel = b.connect(uri.getHost(), uri.getPort()).sync().channel();
            handshaker.handshake(mychannel);
            eventLoopGroup = group;
            // 等待握手完成
            mychannel.closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }



    public static void reconnect() throws Exception {
        if (!mychannel.isActive()) {
            eventLoopGroup.shutdownGracefully();
            connect();
        }
    }




    public static void main(String[] args) throws Exception {

        String uriStr = "ws://192.168.30.12:9527/api/v1/ws?x-auth-token=ilikekunkunjinishizaishitaimei";
        URI uri = new URI(uriStr);
        DefaultHttpHeaders headers = new DefaultHttpHeaders();
        headers.add("x-auth-token", "ilikekunkunjinishizaishitaimei");
        WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(
                uri,
                WebSocketVersion.V13,
                null,           // 子协议
                true,           // 允许无安全（如非 wss）
                headers,        // ✅ 传入自定义 headers
                65536);         // 接收帧最大长度

        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(
                                    new HttpClientCodec(),
                                    new HttpObjectAggregator(8192),
                                    new MyClientHandler(handshaker));
                        }
                    });

            Channel ch = b.connect(uri.getHost(), uri.getPort()).sync().channel();
            handshaker.handshake(ch);

            // 等待握手完成
            ch.closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}
